#include "imbus_internal.h"
#include "im_main_loop.h"

static IMInt
__im_main_loop_add_io_read_watch (IMMainLoop         *loop,
                                  IMIOChannel        *channel,
                                  IMWatchFunc         func,
                                  IMPointer           data,
                                  IMDestroyFunc       data_destroy_func)
{
    return -1;
}

static IMInt
__im_main_loop_add_io_write_watch(IMMainLoop         *loop,
                                  IMIOChannel        *channel,
                                  IMWatchFunc         func,
                                  IMPointer           data,
                                  IMDestroyFunc       data_destroy_func)
{
    return -1;
}

static IMInt
__im_main_loop_add_timeout_watch (IMMainLoop         *loop,
                                  IMInt               interval,
                                  IMWatchFunc         func,
                                  IMPointer           data,
                                  IMDestroyFunc       data_destroy_func)
{
    return -1;
}

IMWatchType
__im_main_loop_get_watch_type (IMMainLoop *loop, IMInt watch_id)
{
    return IM_WATCH_NONE;
}

IMIOChannel*
__im_main_loop_get_watch_io_channel (IMMainLoop *loop, IMInt watch_id)
{
    return 0;
}

IMInt
__im_main_loop_get_watch_timeout (IMMainLoop *loop, IMInt watch_id)
{
    return -1;
}

static IMBool
__im_main_loop_remove_watch (IMMainLoop *loop, IMInt watch_id)
{
    return FALSE;
}

static void
__im_main_loop_run (IMMainLoop *loop)
{
}

static IMBool
__im_main_loop_iteration (IMMainLoop *loop, IMBool may_block)
{
    return FALSE;
}

static void
__im_main_loop_quit (IMMainLoop *loop)
{
}

static IMBool
__im_main_loop_is_running (IMMainLoop *loop)
{
    return FALSE;
}

static void
__im_main_loop_copy (IMPointer      dest,
                     IMConstPointer src)
{
    _im_assert_not_reached("IMMainLoop objects couldn't be copied.\n");
}

static IMBool
__im_main_loop_serialize (IMConstPointer obj,
                          IMPointer      stream)
{
    _im_assert_not_reached("IMMainLoop objects couldn't be serialized.\n");
    return FALSE;
}

static IMBool
__im_main_loop_deserialize (IMPointer      obj,
                            IMPointer      stream)
{
    _im_assert_not_reached("IMMainLoop objects couldn't be deserialized.\n");
    return FALSE;
}

static void
__im_main_loop_class_init (IMPointer klass)
{
    IMObjectClass *ocp = (IMObjectClass *)klass;
    IMMainLoopClass *mcp = (IMMainLoopClass *)klass;

    ocp->copy        = __im_main_loop_copy;
    ocp->serialize   = __im_main_loop_serialize;
    ocp->deserialize = __im_main_loop_deserialize;

    mcp->add_io_read_watch  = __im_main_loop_add_io_read_watch;
    mcp->add_io_write_watch = __im_main_loop_add_io_write_watch;
    mcp->add_timeout_watch  = __im_main_loop_add_timeout_watch;
    mcp->get_watch_type     = __im_main_loop_get_watch_type;
    mcp->get_watch_io_channel = __im_main_loop_get_watch_io_channel;
    mcp->get_watch_timeout  = __im_main_loop_get_watch_timeout;
    mcp->remove_watch       = __im_main_loop_remove_watch;
    mcp->run                = __im_main_loop_run;
    mcp->iteration          = __im_main_loop_iteration;
    mcp->quit               = __im_main_loop_quit;
    mcp->is_running         = __im_main_loop_is_running;
}

static void
__im_main_loop_initialize (IMPointer obj)
{
}

static void
__im_main_loop_finalize (IMPointer obj)
{
}

void
__im_type_register_main_loop ()
{
    static IMTypeInfo im_main_loop_type_info = 
    {
        sizeof (IMMainLoopClass), /**< class_size >**/
        __im_main_loop_class_init, /**< class_init >**/
        0,                          /**< class_finalize >**/

        sizeof (IMMainLoop),      /**< instance_size >**/
        __im_main_loop_initialize, /**< instance_init >**/
        __im_main_loop_finalize,   /**< instance_finalize >**/
    };

    __im_type_register_builtin_class (IM_TYPE_INITIALLY_OWNED,
                                      IM_TYPE_MAIN_LOOP,
                                      "MainLoop",
                                      &im_main_loop_type_info,
                                      FALSE);
}

IMMainLoop*
im_main_loop_new (IMType type)
{
    IMMainLoop *main_loop;
    _im_return_val_if_fail (type != IM_TYPE_MAIN_LOOP &&
                            im_type_is_a (type, IM_TYPE_MAIN_LOOP), 0);
    main_loop = (IMMainLoop *) im_object_new (type);
    _im_assert (main_loop);
    return main_loop;
}

IMInt
im_main_loop_add_io_read_watch (IMMainLoop         *loop,
                                IMIOChannel        *channel,
                                IMWatchFunc         func,
                                IMPointer           data,
                                IMDestroyFunc       data_destroy_func)
{
    _im_return_val_if_fail (IM_IS_MAIN_LOOP(loop), -1);
    _im_return_val_if_fail (IM_IS_IO_CHANNEL(channel), -1);
    _im_return_val_if_fail (func != 0, -1);
    return IM_MAIN_LOOP_GET_CLASS(loop)->add_io_read_watch (loop,
                                                            channel,
                                                            func,
                                                            data,
                                                            data_destroy_func);
}

IMInt
im_main_loop_add_io_write_watch (IMMainLoop         *loop,
                                 IMIOChannel        *channel,
                                 IMWatchFunc         func,
                                 IMPointer           data,
                                 IMDestroyFunc       data_destroy_func)
{
    _im_return_val_if_fail (IM_IS_MAIN_LOOP(loop), -1);
    _im_return_val_if_fail (IM_IS_IO_CHANNEL(channel), -1);
    _im_return_val_if_fail (func != 0, -1);
    return IM_MAIN_LOOP_GET_CLASS(loop)->add_io_write_watch (loop,
                                                             channel,
                                                             func,
                                                             data,
                                                             data_destroy_func);
}

IMInt
im_main_loop_add_timeout_watch (IMMainLoop         *loop,
                                IMInt               timeout,
                                IMWatchFunc         func,
                                IMPointer           data,
                                IMDestroyFunc       data_destroy_func)
{
    _im_return_val_if_fail (IM_IS_MAIN_LOOP(loop), -1);
    _im_return_val_if_fail (timeout > 0, -1);
    _im_return_val_if_fail (func != 0, -1);
    return IM_MAIN_LOOP_GET_CLASS(loop)->add_timeout_watch (loop,
                                                            timeout,
                                                            func,
                                                            data,
                                                            data_destroy_func);
}

IMWatchType
im_main_loop_get_watch_type (IMMainLoop *loop, IMInt watch_id)
{
    _im_return_val_if_fail (IM_IS_MAIN_LOOP(loop), FALSE);
    _im_return_val_if_fail (watch_id >= 0, FALSE);
    return IM_MAIN_LOOP_GET_CLASS(loop)->get_watch_type (loop, watch_id);
}

IMIOChannel*
im_main_loop_get_watch_io_channel (IMMainLoop *loop, IMInt watch_id)
{
    _im_return_val_if_fail (IM_IS_MAIN_LOOP(loop), FALSE);
    _im_return_val_if_fail (watch_id >= 0, FALSE);
    return IM_MAIN_LOOP_GET_CLASS(loop)->get_watch_io_channel (loop, watch_id);
}

IMInt
im_main_loop_get_watch_timeout (IMMainLoop *loop, IMInt watch_id)
{
    _im_return_val_if_fail (IM_IS_MAIN_LOOP(loop), FALSE);
    _im_return_val_if_fail (watch_id >= 0, FALSE);
    return IM_MAIN_LOOP_GET_CLASS(loop)->get_watch_timeout (loop, watch_id);
}

IMBool
im_main_loop_remove_watch (IMMainLoop *loop, IMInt watch_id)
{
    _im_return_val_if_fail (IM_IS_MAIN_LOOP(loop), FALSE);
    _im_return_val_if_fail (watch_id >= 0, FALSE);
    return IM_MAIN_LOOP_GET_CLASS(loop)->remove_watch (loop, watch_id);
}

void
im_main_loop_run (IMMainLoop *loop)
{
    _im_return_if_fail (IM_IS_MAIN_LOOP(loop));
    IM_MAIN_LOOP_GET_CLASS(loop)->run (loop);
}

IMBool
im_main_loop_iteration (IMMainLoop *loop, IMBool may_block)
{
    _im_return_val_if_fail (IM_IS_MAIN_LOOP(loop), FALSE);
    return IM_MAIN_LOOP_GET_CLASS(loop)->iteration (loop, may_block);
}

void
im_main_loop_quit (IMMainLoop *loop)
{
    _im_return_if_fail (IM_IS_MAIN_LOOP(loop));
    IM_MAIN_LOOP_GET_CLASS(loop)->quit (loop);
}

IMBool
im_main_loop_is_running (IMMainLoop *loop)
{
    _im_return_val_if_fail (IM_IS_MAIN_LOOP(loop), FALSE);
    return IM_MAIN_LOOP_GET_CLASS(loop)->is_running (loop);
}

/*
vi:ts=4:nowrap:ai:expandtab
*/
